package com.cleaningcloud.cld.service.impl;

import com.cleaningcloud.cld.domain.CldAssetsDepreciation;
import com.cleaningcloud.cld.domain.CldAssetsRecord;
import com.cleaningcloud.cld.domain.dto.CldAssetsDepreciationDto;
import com.cleaningcloud.cld.domain.dto.CldAssetsRecordDto;
import com.cleaningcloud.cld.domain.dto.CldAssetsRecordProjectDto;
import com.cleaningcloud.cld.domain.vo.CldAssetsDepreciationVo;
import com.cleaningcloud.cld.domain.vo.CldAssetsRecordVo;
import com.cleaningcloud.cld.domain.vo.CldAssetsRepairDetailsVo;
import com.cleaningcloud.cld.domain.vo.CldAssetsRepairVo;
import com.cleaningcloud.cld.mapper.CldAssetsDetailsMapper;
import com.cleaningcloud.cld.mapper.CldAssetsRecordMapper;
import com.cleaningcloud.cld.mapper.CldAssetsRepairMapper;
import com.cleaningcloud.cld.service.ICldAssetsDepreciationService;
import com.cleaningcloud.cld.service.ICldAssetsRecordService;
import com.cleaningcloud.common.core.constant.SecurityConstants;
import com.cleaningcloud.common.core.utils.DateUtils;
import com.cleaningcloud.common.security.utils.SecurityUtils;
import com.cleaningcloud.erp.api.RemoteWareService;
import com.cleaningcloud.erp.api.domain.ErpWareCommodityNumber;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;

/**
 * 资产记录Service业务层处理
 *
 * @author cleaningcloud
 * @date 2024-10-06
 */
@Service
public class CldAssetsRecordServiceImpl implements ICldAssetsRecordService {
    @Autowired
    private CldAssetsRecordMapper cldAssetsRecordMapper;

    @Autowired
    private CldAssetsDetailsMapper cldAssetsDetailsMapper;

    @Autowired
    private ICldAssetsDepreciationService cldAssetsDepreciationService;

    @Autowired
    private CldAssetsRepairMapper cldAssetsRepairMapper;

    @Autowired
    private RemoteWareService remoteWareService;

    /**
     * 查询资产记录
     *
     * @param assetsRecordId 资产记录主键
     * @return 资产记录
     */
    @Override
    public CldAssetsRecordVo selectCldAssetsRecordByAssetsRecordId(Long assetsRecordId) {
        return cldAssetsRecordMapper.selectCldAssetsRecordByAssetsRecordId(assetsRecordId);
    }

    /**
     * 查询资产记录列表
     *
     * @param cldAssetsRecord 资产记录
     * @return 资产记录
     */
    @Override
    public List<CldAssetsRecordVo> selectCldAssetsRecordList(CldAssetsRecordDto cldAssetsRecord) {
        return cldAssetsRecordMapper.selectCldAssetsRecordList(cldAssetsRecord);
    }

    @Override
    public List<CldAssetsRecordVo> getRepairList(CldAssetsRecord cldAssetsRecord) {
        return cldAssetsRecordMapper.getRepairList(cldAssetsRecord);
    }

    /**
     * 新增资产记录
     *
     * @param cldAssetsRecord 资产记录
     * @return 结果
     */
    @Override
    @Transactional
    public int insertCldAssetsRecord(CldAssetsRecordDto cldAssetsRecord) {
        CldAssetsRecord assetsRecord = cldAssetsRecordMapper.selectCldAssetsRecordByAssetsRecordId(cldAssetsRecord.getAssetsRecordId());
        if (assetsRecord != null) {
            assetsRecord.setOperaUserTime(new Date());
            assetsRecord.setOperaUserId(SecurityUtils.getUserId());
            assetsRecord.setIsNewUpdate(0L);
            // 闲置中 设置闲置结束时间
            if (assetsRecord.getRecordStatus() == 1) {
                assetsRecord.setLdleEndTime(DateUtils.getNowDate());
            }
            // 投放中 设置投放结束时间
            if (assetsRecord.getRecordStatus() == 2) {
                assetsRecord.setPlacementEndTime(DateUtils.getNowDate());
            }
            // 维修中 设置维修时间
            if (assetsRecord.getRecordStatus() == 3) {
                assetsRecord.setRepairTime(DateUtils.getNowDate());
            }
            cldAssetsRecordMapper.updateCldAssetsRecord(assetsRecord);
            CldAssetsRecord newAssetsRecord = new CldAssetsRecord();
            // 如传入状态为空 则为确认维修 维修完成后继续投放
            if (cldAssetsRecord.getRecordStatus() == null) {
                // 查找当前资产记录上一条状态
                cldAssetsRecord.setRecordStatus(assetsRecord.getLastStatus());
                cldAssetsRecord.setProjectId(assetsRecord.getProjectId());
                cldAssetsRecord.setPersonId(assetsRecord.getPersonId());
                // 取维修日期
                newAssetsRecord.setRepairTime(assetsRecord.getRepairTime());
                // 去闲置时间
                newAssetsRecord.setLdleStartTime(assetsRecord.getLdleStartTime());
                // 更改配件库存
                ErpWareCommodityNumber query = new ErpWareCommodityNumber();
                CldAssetsRepairVo cldAssetsRepairVo = cldAssetsRepairMapper.getRepairDetailsByRecordId(assetsRecord.getAssetsRecordId());
                for (CldAssetsRepairDetailsVo cldAssetsRepairDetailsVo : cldAssetsRepairVo.getDetailsList()) {
                    // 根据商品id和调出仓库id查询对应库存数据
                    query.setWareId(cldAssetsRepairDetailsVo.getWareId());
                    query.setCommodityId(cldAssetsRepairDetailsVo.getCommodityId());
                    ErpWareCommodityNumber out = remoteWareService.selectByCommodityIdAndWareId(query, SecurityConstants.INNER);
                    // 根据调拨数量进行库存相减
                    if (out.getCommodityNumber() < cldAssetsRepairDetailsVo.getAssetsRepairNumber()) {
                        throw new RuntimeException("当前仓库库存数量小于维修数量");
                    }
                    out.setCommodityNumber(out.getCommodityNumber() - cldAssetsRepairDetailsVo.getAssetsRepairNumber());
                    remoteWareService.updateErpWareCommodityNumber(out, SecurityConstants.INNER);
                }
            }
            newAssetsRecord.setAssetsId(assetsRecord.getAssetsId());
            newAssetsRecord.setAssetsIdCard(assetsRecord.getAssetsIdCard());
            newAssetsRecord.setFlag(0L);
            newAssetsRecord.setIsNewUpdate(1L);
            newAssetsRecord.setCreateTime(new Date());
            newAssetsRecord.setOperaUserTime(new Date());
            newAssetsRecord.setLastStatus(assetsRecord.getRecordStatus());
            newAssetsRecord.setOperaUserId(SecurityUtils.getUserId());
            newAssetsRecord.setLdleStartTime(cldAssetsRecord.getRecordStatus() == 1 ? DateUtils.getNowDate() : assetsRecord.getLdleStartTime());
            newAssetsRecord.setPlacementStartTime(cldAssetsRecord.getRecordStatus() == 2 ? DateUtils.getNowDate() : assetsRecord.getPlacementStartTime());
            // 投放
            if (cldAssetsRecord.getRecordStatus() == 2) {
                newAssetsRecord.setProjectId(cldAssetsRecord.getProjectId());
                newAssetsRecord.setPersonId(cldAssetsRecord.getPersonId());
//                // 新增资产折旧信息
//                getCldAssetsDepreciation(assetsRecord, newAssetsRecord);
            }
            // 维修
            if (cldAssetsRecord.getRecordStatus() == 3) {
                newAssetsRecord.setRepairUserId(cldAssetsRecord.getRepairUserId());
                newAssetsRecord.setRepairDesc(cldAssetsRecord.getRepairDesc());
                newAssetsRecord.setRepairImgs(cldAssetsRecord.getRepairImgs());
                newAssetsRecord.setRecordStatus(cldAssetsRecord.getRecordStatus());
                newAssetsRecord.setRepairMoney(cldAssetsRecord.getRepairMoney());
                newAssetsRecord.setWareId(cldAssetsRecord.getWareId() == null ? 10 : cldAssetsRecord.getWareId());
                newAssetsRecord.setReportUserId(SecurityUtils.getUserId());
                newAssetsRecord.setReportTime(DateUtils.getNowDate());
                newAssetsRecord.setReportDesc(cldAssetsRecord.getReportDesc());
                newAssetsRecord.setReportImgs(cldAssetsRecord.getReportImgs());
                newAssetsRecord.setRepairStatus(cldAssetsRecord.getRepairStatus());

                // 投放中报修
                if (assetsRecord.getRecordStatus() == 2) {
                    newAssetsRecord.setProjectId(assetsRecord.getProjectId());
                    newAssetsRecord.setPersonId(assetsRecord.getPersonId());
                }
            }
            // 报废
            if (cldAssetsRecord.getRecordStatus() == 4) {
                newAssetsRecord.setScrapTime(cldAssetsRecord.getScrapTime() == null ? DateUtils.getNowDate() : cldAssetsRecord.getScrapTime());
                newAssetsRecord.setScrapUserId(SecurityUtils.getUserId());
                newAssetsRecord.setScrapDesc(cldAssetsRecord.getScrapDesc());
                newAssetsRecord.setProjectId(assetsRecord.getProjectId());
                newAssetsRecord.setPersonId(cldAssetsRecord.getPersonId());
            }
            newAssetsRecord.setRecordStatus(cldAssetsRecord.getRecordStatus());
            cldAssetsRecordMapper.insertCldAssetsRecord(newAssetsRecord);
            // 新增资产维修配件明细
            if (cldAssetsRecord.getRecordStatus() == 3) {
                if (!cldAssetsRecord.getDetailsList().isEmpty()) {
                    cldAssetsRecord.getDetailsList().forEach(item -> {
                        item.setAssetsRecordId(newAssetsRecord.getAssetsRecordId());
                    });
                    cldAssetsRepairMapper.batchInsertRepairDetails(cldAssetsRecord.getDetailsList());
                }
            }
        }
        return 1;
    }

    @Override
    @Transactional
    public int batchInsertCldAssetsRecord(CldAssetsRecordProjectDto assetsRecordProjectDto) {
        for (CldAssetsRecord assetsRecordDto : assetsRecordProjectDto.getAssetsRecords()) {
            CldAssetsRecordDto cldAssetsRecordDto = new CldAssetsRecordDto();
            BeanUtils.copyProperties(assetsRecordDto, cldAssetsRecordDto);
            this.insertCldAssetsRecord(cldAssetsRecordDto);
        }
        return 1;
    }

    /**
     * 组装资产折旧
     *
     * @param assetsRecord
     * @param newAssetsRecord
     */
    private void getCldAssetsDepreciation(CldAssetsRecord assetsRecord, CldAssetsRecord newAssetsRecord) {
        LocalDate currentDate = LocalDate.now();
        // 当月已有折旧信息则不新增
        CldAssetsDepreciationDto query = new CldAssetsDepreciationDto();
        query.setYear(currentDate.getYear());
        query.setMonth(currentDate.getMonthValue());
        query.setAssetsIdCard(assetsRecord.getAssetsIdCard());
        List<CldAssetsDepreciationVo> list = cldAssetsDepreciationService.selectCldAssetsDepreciationList(query);
        if (list == null || list.isEmpty()) {
            CldAssetsDepreciation cldAssetsDepreciation = getCldAssetsDepreciation(assetsRecord, newAssetsRecord, currentDate);
            cldAssetsDepreciationService.insertCldAssetsDepreciation(cldAssetsDepreciation);
        }
    }

    @NotNull
    private CldAssetsDepreciation getCldAssetsDepreciation(CldAssetsRecord assetsRecord, CldAssetsRecord newAssetsRecord, LocalDate currentDate) {
        CldAssetsDepreciation cldAssetsDepreciation = new CldAssetsDepreciation();
        cldAssetsDepreciation.setAssetsId(assetsRecord.getAssetsId());
        cldAssetsDepreciation.setAssetsIdCard(assetsRecord.getAssetsIdCard());
        cldAssetsDepreciation.setLossType(1L);
        cldAssetsDepreciation.setYear(currentDate.getYear());
        cldAssetsDepreciation.setMonth(currentDate.getMonthValue());
        cldAssetsDepreciation.setDay(currentDate.getDayOfMonth());
        cldAssetsDepreciation.setProjectId(newAssetsRecord.getProjectId());
        cldAssetsDepreciation.setStatus(1L);
        return cldAssetsDepreciation;
    }


    /**
     * 修改资产记录
     *
     * @param cldAssetsRecord 资产记录
     * @return 结果
     */
    @Override
    public int updateCldAssetsRecord(CldAssetsRecord cldAssetsRecord) {
        return cldAssetsRecordMapper.updateCldAssetsRecord(cldAssetsRecord);
    }

    @Override
    public int auditCldAssetsRecord(CldAssetsRecord cldAssetsRecord) {
        CldAssetsRecord assetsRecord = cldAssetsRecordMapper.selectCldAssetsRecordByAssetsRecordId(cldAssetsRecord.getAssetsRecordId());
        if (assetsRecord == null) {
            throw new RuntimeException("资产记录查询失败！");
        }
        assetsRecord.setScrapStatus(cldAssetsRecord.getScrapStatus());
        assetsRecord.setScrapApproveTime(DateUtils.getNowDate());
        assetsRecord.setScrapApproveId(SecurityUtils.getUserId());
        return cldAssetsRecordMapper.updateCldAssetsRecord(assetsRecord);
    }

    /**
     * 批量删除资产记录
     *
     * @param assetsRecordIds 需要删除的资产记录主键
     * @return 结果
     */
    @Override
    public int deleteCldAssetsRecordByAssetsRecordIds(Long[] assetsRecordIds) {
        return cldAssetsRecordMapper.deleteCldAssetsRecordByAssetsRecordIds(assetsRecordIds);
    }

    /**
     * 删除资产记录信息
     *
     * @param assetsRecordId 资产记录主键
     * @return 结果
     */
    @Override
    public int deleteCldAssetsRecordByAssetsRecordId(Long assetsRecordId) {
        return cldAssetsRecordMapper.deleteCldAssetsRecordByAssetsRecordId(assetsRecordId);
    }
}
